package com.destroyer.user.ability.impl.auth;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.fastjson.JSON;
import com.destroyer.common.constant.DicConstant;
import com.destroyer.common.entity.auth.AuthBaseVO;
import com.destroyer.common.entity.auth.AuthLoginBO;
import com.destroyer.common.entity.auth.AuthUserInfoVO;
import com.destroyer.common.entity.auth.AuthUserRoleVO;
import com.destroyer.common.entity.system.ResultEnum;
import com.destroyer.common.exception.ServiceException;
import com.destroyer.common.util.DateUtils;
import com.destroyer.core.entity.userInfo.bo.UserInfoQueryBO;
import com.destroyer.core.entity.userInfo.vo.UserInfoVO;
import com.destroyer.user.ability.auth.IAuthLoginAbilityService;
import com.destroyer.user.service.userInfo.IUserInfoGetListService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 标题：AuthLoginAbilityServiceImpl
 * 说明：
 * 时间：2024/2/28
 * 作者：admin
 */
@Service
public class AuthLoginAbilityServiceImpl implements IAuthLoginAbilityService {

    @Autowired
    private IUserInfoGetListService userInfoGetListService;

    /**
     * JWT KEY
     */
    @Value("${jwt-key}")
    private String jwtKey;

    /**
     * 过期时间
     */
    @Value("${access-token-expires}")
    private Integer accessTokenExpires;

    /**
     * 密码前后盐
     */
    @Value("${pwd-salt-s}")
    private String pwdSaltS;
    @Value("${pwd-salt-e}")
    private String pwdSaltE;

    /**
     * 系统用户登录
     *
     * @param req
     * @return
     */
    @Override
    public AuthBaseVO<AuthUserInfoVO> login(AuthLoginBO req) {
        AuthBaseVO<AuthUserInfoVO> rsp;
        //入参效验
        this.validParams(req);
        //执行核心逻辑前调用
        this.beforeToDo(req);

        UserInfoQueryBO userInfoQueryBO = new UserInfoQueryBO();
        userInfoQueryBO.setUsercode(req.getAccount());
        userInfoQueryBO.setPassword(req.getPwd());
        List<UserInfoVO> list = userInfoGetListService.getList(userInfoQueryBO);
        if(null == list || list.size() == 0){

            throw new ServiceException(ResultEnum.FAILURE,"登录用户不存在！");
        }
        if(list.size() > 1){
            throw new ServiceException(ResultEnum.FAILURE,"用户数据异常，存在多个用户！");
        }
        UserInfoVO userInfoVO = list.get(0);
        if(!DicConstant.USER_STATE.NORMAL.equals(userInfoVO.getUserState())){
            throw new ServiceException(ResultEnum.FAILURE,"用户状态异常");

        }
        //携带密码在查询
        userInfoQueryBO.setPassword(req.getPwd());
        list = userInfoGetListService.getList(userInfoQueryBO);
        if(list.size() == 0){
            throw new ServiceException(ResultEnum.FAILURE,"密码错误！");
        }

        userInfoVO = list.get(0);
        rsp = this.buildAuthInfo(userInfoVO);
        this.buildRsp(rsp);
        return rsp;
    }
    /**
     * 构造授权身份信息
     * @param req
     * @return
     */
    private AuthBaseVO<AuthUserInfoVO> buildAuthInfo(UserInfoVO req){
        AuthBaseVO<AuthUserInfoVO> rsp = new AuthBaseVO<>();
        AuthUserInfoVO authUserInfoVO = new AuthUserInfoVO();
        BeanUtils.copyProperties(req,authUserInfoVO);
        if(null != req.getRole()){
            AuthUserRoleVO authUserRoleVO = new AuthUserRoleVO();
            BeanUtils.copyProperties(req.getRole(),authUserRoleVO);
            authUserInfoVO.setRole(authUserRoleVO);
        }

        rsp.setAuth(authUserInfoVO);
        return rsp;
    }

    /**
     * 构造出参
     * @param authBaseVO
     */
    private void buildRsp(AuthBaseVO<AuthUserInfoVO> authBaseVO){
        Date currentDateYYYYMMDDHHMMSS = DateUtils.getCurrentDateYYYYMMDDHHMMSS();
        authBaseVO.setLoginTime(currentDateYYYYMMDDHHMMSS);
        authBaseVO.setSysRole(authBaseVO.getAuth().getSysRole());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDateYYYYMMDDHHMMSS);
        calendar.add(Calendar.SECOND, accessTokenExpires);
        authBaseVO.setExpireTime(calendar.getTime());
        Map map = JSON.parseObject(JSON.toJSONString(authBaseVO), Map.class);
        String token = JWTUtil.createToken(map, this.jwtKey.getBytes());
        authBaseVO.setToken(token);

    }


    /**
     * 类通用入参校验
     *
     * @param req
     */
    private void validParams(AuthLoginBO req) {
        if (null == req) {
            throw new ServiceException(ResultEnum.PARAM_MISS, "入参不能为空");
        } else {
            if(StringUtils.isBlank(req.getAccount())){
                throw new ServiceException(ResultEnum.PARAM_MISS,"登录账号不能为空！");
            }
            if(StringUtils.isBlank(req.getPwd())){
                throw new ServiceException(ResultEnum.PARAM_MISS,"登录密码不能为空！");
            }
        }
    }

    /**
     * 类通用执行前调用逻辑
     *
     * @param req 入参
     */
    private void beforeToDo(AuthLoginBO req) {
        // TODO 执行前调用逻辑
        String password = SecureUtil.md5(pwdSaltS+req.getPwd()+pwdSaltE);
        req.setPwd(password);
    }
}
